﻿
#include "HttpHandles.h"

std::map<std::string, std::string> CHttpHandles::gTokens;
CSqlData CHttpHandles::gSqlData;

CHttpHandles::CHttpHandles()
{
}

CHttpHandles::~CHttpHandles()
{
}

#define HTTP_VERSION  "HTTP/1.1 "
#define HTTPERROR_RESPONSE_204 "204 No Content\r\n"
#define HTTPERROR_RESPONSE_200 "200 OK\r\n"

void __stdcall CHttpHandles::ErrorHandle(PHTTPINFO pHttpInfo)
{
    LOG("CHttpHandles::ErrorHandle:\n%s\n\n", pHttpInfo->Buffer);
    RequestError(pHttpInfo, "无效的请求");
}

void __stdcall CHttpHandles::General(PHTTPINFO pHttpInfo)
{
    HANDLE hFile = INVALID_HANDLE_VALUE;
    char* Buffer = NULL;
    DWORD dwRead = 0;
    char strFilePath[MAX_PATH] = { 0 };
    // 获取当前目录
    dwRead = GetCurrentDirectoryA(MAX_PATH, strFilePath);
    memcpy_s(strFilePath + dwRead, MAX_PATH - dwRead,
        pHttpInfo->strPath, pHttpInfo->nPathSize);
    BOOL bOK = FALSE;
    do
    {
        // 打开文件
        hFile = CreateFileA(
            strFilePath,                // 文件路径
            GENERIC_READ,            // 读取权限
            FILE_SHARE_READ,         // 共享模式（允许读取共享）
            NULL,                    // 默认安全属性
            OPEN_EXISTING,           // 文件必须存在
            FILE_ATTRIBUTE_NORMAL,   // 普通文件
            NULL                     // 无模板文件
        );
        if (hFile == INVALID_HANDLE_VALUE) {
            break;
        }

        // 获取文件大小
        LARGE_INTEGER fileSize;
        if (!GetFileSizeEx(hFile, &fileSize)) {
            break;
        }

        // 文件大小检查
        if (fileSize.HighPart > 0 || fileSize.LowPart > 1024 * 1024) {
            break;
        }

        // 分配内存
        Buffer = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, fileSize.LowPart + 1);
        if (!Buffer) {
            break;
        }

        // 读取文件内容
        if (!ReadFile(hFile, Buffer, fileSize.LowPart, &dwRead, NULL)) {
            break;
        }

        // 确保读取的字节数与文件大小一致
        if (dwRead != fileSize.LowPart) {
            break;
        }

        bOK = TRUE;

    } while (FALSE);

    if (hFile && hFile != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hFile);
    }



    if (!bOK)
    {
        ErrorHandle(pHttpInfo);
    }
    else
    {
        LOG("CHttpHandles::Response:\n%s\n\n", Buffer);
        char strContentLength[64] = { 0 };
        fileio_write(pHttpInfo->hHttp, HTTP_VERSION HTTPERROR_RESPONSE_200,
            strlen(HTTP_VERSION) + strlen(HTTPERROR_RESPONSE_200));
        sprintf(strContentLength, "content-length: %d\r\n\r\n", dwRead);
        fileio_write(pHttpInfo->hHttp, strContentLength, strlen(strContentLength));
        fileio_write(pHttpInfo->hHttp, Buffer, dwRead);
    }
   
    if (Buffer)
    {
        HeapFree(GetProcessHeap(), 0, Buffer);
    }
    return;
}

void __stdcall CHttpHandles::HeartBeat(PHTTPINFO pHttpInfo)
{
    Json::Value request;
    Json::Value response;

    if (false == TakeRequest(pHttpInfo, request))
    {
        RequestError(pHttpInfo, "参数无效");
        return;
    }

    do {
        std::string access = request["access"].asString();
        std::string token = request["token"].asString();
        auto it = gTokens.find(access);
        
        if (it != gTokens.end() && token == it->second)
        {
            response["code"] = 0;
            response["message"] = "心跳正常";
        }
        else
        {
            response["code"] = 1;
            response["message"] = "错误的心跳信息";
        }
    } while (0);
    
    Response(pHttpInfo, response);
}

void __stdcall CHttpHandles::Login(PHTTPINFO pHttpInfo)
{
    Json::Value request;
    Json::Value response;

    if (false == TakeRequest(pHttpInfo, request))
    {
        RequestError(pHttpInfo, "参数无效");
        return;
    }
    std::string access = request["access"].asString();
    std::string password = request["password"].asString();
    auto it = gTokens.find(access);

    do {
        if (it == gTokens.end()) {
            Json::Value info;
            //if (TakeUserInfo(access, password, info))
            if(TRUE)
            {
                info["username"] = (char*)"系统管理员";
                info["email"] = (char*)"";

                GUID guid;
                char token[39];
                CoCreateGuid(&guid);
                snprintf(token, sizeof(token), "{%08x-%04x-%04x-%04x-%012llx}",
                    guid.Data1, guid.Data2, guid.Data3, (guid.Data4[0] << 8) | guid.Data4[1],
                    *((unsigned long long*) & guid.Data4[2]));
                info["token"] = token;
                gTokens["access"] = token;

                response["code"] = 0;
                response["message"] = "登录成功";
                response["data"] = info;
            }
            else
            {
                response["code"] = 1;
                response["message"] = "请检查密码是否正确";
            }
        }
        else
        {
            response["code"] = 1;
            response["message"] = "用户已经登录";
        }
    } while (0);

    Response(pHttpInfo, response);
}

void __stdcall CHttpHandles::Logout(PHTTPINFO pHttpInfo)
{
    Json::Value request;
    Json::Value response;

    if (false == TakeRequest(pHttpInfo, request))
    {
        RequestError(pHttpInfo, "参数无效");
        return;
    }

    std::string access = request["access"].asString();
    std::string token = request["token"].asString();
    auto it = gTokens.find(access);

    do {
        if (it != gTokens.end() && token == it->second)
        {
            gTokens.erase(access);
            response["code"] = 0;
            response["message"] = "注销成功";
        }
        else
        {
            response["code"] = 1;
            response["message"] = "错误的注销信息";
        }
    } while (0);

    Response(pHttpInfo, response);
}

void __stdcall CHttpHandles::GetPermissions(PHTTPINFO pHttpInfo)
{
    Json::Value request;
    Json::Value response;

    if (false == TakeRequest(pHttpInfo, request))
    {
        RequestError(pHttpInfo, "参数无效");
        return;
    }

    std::string access = request["access"].asString();
    std::string token = request["token"].asString();

    auto it = gTokens.find(access);
    do {
        if (it != gTokens.end() && token == it->second)
        {
            Json::Value permissions;
            if (true == TakePermissions(access, permissions))
            {
                response["code"] = 0;
                response["message"] = "获取用户权限成功";
                response["data"] = permissions;
            }
            else
            {
                response["code"] = 1;
                response["message"] = "获取用户权限失败";
            }
        }
        else
        {
            response["code"] = 2;
            response["message"] = "用户未登录";
        }
    } while (0);


    Response(pHttpInfo, response);
}

bool CHttpHandles::TakeRequest(PHTTPINFO pHttpInfo, Json::Value& request)
{
    LOG("CHttpHandles::TakeRequest:\n%s\n\n", pHttpInfo->Buffer);
    if (0 != _stricmp(pHttpInfo->strModle, "post"))
    {
        return false;
    }

    Json::Reader reader;
    // 消息接受完成
    if (!reader.parse(&pHttpInfo->Buffer[pHttpInfo->nCheckOffset],
        &pHttpInfo->Buffer[pHttpInfo->nCheckOffset] + pHttpInfo->nContentLength, request, true))
    {
        return false;
    }

    return true;
}

bool CHttpHandles::TakePermissions(const std::string& access, Json::Value& root)
{
    return gSqlData.TakePermissions(access, root);
}

bool CHttpHandles::TakeUserInfo(const std::string& access, const std::string& password, Json::Value& root)
{
    return gSqlData.TakeUserInfo(access, password, root);
}

bool CHttpHandles::Response(PHTTPINFO pHttpInfo, const Json::Value& response)
{
    std::string message = response.toStyledString();
    LOG("CHttpHandles::Response:\n%s\n\n", message.c_str());
    char strContentLength[64] = { 0 };
    fileio_write(pHttpInfo->hHttp, HTTP_VERSION HTTPERROR_RESPONSE_200,
        strlen(HTTP_VERSION) + strlen(HTTPERROR_RESPONSE_200));
    sprintf(strContentLength, "content-length: %d\r\n\r\n", message.length());
    fileio_write(pHttpInfo->hHttp, strContentLength, strlen(strContentLength));
    fileio_write(pHttpInfo->hHttp, message.c_str(), message.length());
    return true;
}

bool CHttpHandles::RequestError(PHTTPINFO pHttpInfo, const std::string& message)
{
    std::string response;
    Json::Value root;
    root["code"] = 1;
    root["message"] = message;
    response = root.toStyledString();
    LOG("CHttpHandles::RequestError:\n%s\n\n", response.c_str());
    char strContentLength[64] = { 0 };
    fileio_write(pHttpInfo->hHttp, HTTP_VERSION HTTPERROR_RESPONSE_204,
        strlen(HTTP_VERSION) + strlen(HTTPERROR_RESPONSE_204));
    sprintf(strContentLength, "content-length: %d\r\n\r\n", response.length());
    fileio_write(pHttpInfo->hHttp, strContentLength, strlen(strContentLength));
    fileio_write(pHttpInfo->hHttp, response.c_str(), response.length());
    return true;
}